<?php
namespace App\Http\Controllers\Admin;


use App\Models\BudgetRowChange;
use App\Models\Formula;
use App\Models\Member;
use App\Models\Project;
use App\Models\Settlement;
use Illuminate\Http\Request;
use App\Models\Budget;
use App\Models\BudgetRow;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Input;
use Illuminate\Support\Facades\URL;

class BudgetController extends Controller
{

    public function __construct(){
        // 导航设置
        view()->share('buget',1);
    }

    /**
     * Display the specified resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index( Request $request ){
        $pid            = $request->get("pid");
        $project_id     = $request->get("id");
        $settlements    = Settlement::where("project_id" ,"=" ,$pid)->get();//Settlement::where("project_id" ,"=" ,$pid)->where("id","<>",$project_id)->get();
        $Budgets        = $this->getBudget2($project_id);//$this->getBudget( $project_id );
        $EmptySheet     = [
            "id"=>0,
            "cell"=>[],
            "formulae"=>[],
            "mergeCells"=>[],
            "rows"=> $this->getEmptySheetData(50 ,50),
            "columns" => $this->getEmptyColumns(50)
        ];
        return view('admin.budget.index',array("pid"=>$pid ,"project_id"=>$project_id ,"sheets"=> $Budgets ,"empty_sheet"=> json_encode($EmptySheet),"settlements"=>$settlements));
    }



    public function download(Request $request , $pid ,$id){
        $Settlement = Settlement::where("id" ,"=" ,$pid)->first();
        $Budgets    = Budget::where("project_id" ,"=" ,$id)->orderBy('budget_id', 'asc')->get();
        $excel = App::make("excel");
        $excel->create($Settlement->name,function($excel) use($Budgets){
            foreach($Budgets as $Budget) {
                $BudgetRows = BudgetRow::where("budget_id", "=", $Budget->budget_id)->orderBy('budget_row_id', 'asc')->get();
                if(count($BudgetRows) == 0){
                    continue;
                }
                $Rows = [];
                foreach ($BudgetRows as $BudgetRow){
                    $tmp_row = json_decode($BudgetRow->row_data ,true);
                    array_unshift($tmp_row ,"");
                    $Rows[] = $tmp_row;
                }

                $excel->sheet('sheet', function($sheet) use ($Rows ,$Budget){
                    $sheet->setWidth(array('A' =>  10));
                    $sheet->rows($Rows);
                    $sheet_config = json_decode($Budget->sheet_data ,true);
                    $mergeCellsStyle = [];
                    for( $i = 0 ; $i < count($sheet_config["cell"]) ;$i++){
                        $cell_cfg = $sheet_config["cell"][$i];
                        $key = $cell_cfg["row"] . "-" . $cell_cfg["col"];
                        if(isset( $cell_cfg["color"] ) || isset( $cell_cfg["className"])){
                            $mergeCellsStyle[ $key ] = array() ;
                        }
                        if(isset( $cell_cfg["color"] )){
                            $rgb = str_replace("rgb(" ,"",$cell_cfg["color"]);
                            $rgb = explode(",",str_replace(")" ,"" ,$rgb));
                            $cell_cfg["color"] = $this->rgb2html($rgb[0], $rgb[1], $rgb[2]);
                            $mergeCellsStyle[ $key ]["color"] = $cell_cfg["color"];
                        }
                        if(isset( $cell_cfg["className"])){
                            if(false !== strpos($cell_cfg["className"] ,"htCenter")){
                                $cell_cfg["alignment"] = "center";
                                $mergeCellsStyle[ $key ]["alignment"] = $cell_cfg["alignment"];
                            }
                            if(false !== strpos($cell_cfg["className"] ,"htMiddle")){
                                $cell_cfg["valignment"] = \PHPExcel_Style_Alignment::VERTICAL_CENTER;
                                $mergeCellsStyle[ $key ]["valignment"] = $cell_cfg["valignment"];
                            }
                        }
                        if (isset($cell_cfg["bt"])){
                            $rgb = str_replace("rgb(" ,"",$cell_cfg["bt"]);
                            $rgb = explode(",",str_replace(")" ,"" ,$rgb));
                            $cell_cfg["bt"] = $this->rgb2html($rgb[0], $rgb[1], $rgb[2]);
                            $mergeCellsStyle[ $key ]["bt"] = $cell_cfg["bt"];
                        }

                        $colString = $this->stringFromColumnIndex( $cell_cfg["col"] ) . ($cell_cfg["row"] + 1);
                        $sheet->cell($colString, function($cell) use($cell_cfg) {
                            if(isset( $cell_cfg["color"] )){
                                $cell->setBackground( $cell_cfg["color"] );
                            }
                            if(isset( $cell_cfg["alignment"])) {
                                $cell->setAlignment($cell_cfg["alignment"]);
                            }
                            if(isset( $cell_cfg["valignment"] )) {
                                $cell->setValignment( \PHPExcel_Style_Alignment::VERTICAL_CENTER );
                            }
                            if(isset( $cell_cfg["bt"] )) {
                               //$sheet->setBorder('B16:T16', 'thin', "D8572C");
//                                $cell->setBorder(array(
//                                    'borders' => array(
//                                        'top'   => array(
//                                            'style' => 'solid',
//                                            'color' => $cell_cfg["bt"]
//                                        ),
//                                    )
//                                ));
                            }
                        });
                    }
                    for( $i = 0 ; $i < count($sheet_config["mergeCells"]) ;$i++){
                        $mergeCells = $sheet_config["mergeCells"][$i];
                        $begin = (int)$mergeCells["col"];
                        $end = $begin + (int)$mergeCells["colspan"] - 1;
                        $bC = $this->stringFromColumnIndex( $mergeCells["col"] ) . ($mergeCells["row"] + 1);
                        $eC = $this->stringFromColumnIndex( $end ) . ( (int)$mergeCells["rowspan"]+  $mergeCells["row"]);
                        $sheet->mergeCells("$bC:$eC");
                        $key = $mergeCells["row"] . "-" . $mergeCells["col"];
                        if(isset($mergeCellsStyle[ $key ])){
                            $style = $mergeCellsStyle[ $key ];
                            $sheet->cells("$bC:$eC", function($cells) use($style) {
                                //背景颜色
                                if(isset( $style["color"] )){
                                    $cells->setBackground( $style["color"] );
                                }
                                //居中
                                if(isset( $style["alignment"])){
                                    $cells->setAlignment( $style["alignment"] );
                                }
                                //垂直居中
                                if(isset( $style["valignment"]) ){
                                    $cells->setValignment( $style["valignment"] );
                                }
                                $cells->setBorder('solid', 'none', 'none', 'solid');
                                /*
                                $cells->setBorder(array(
                                    'borders' => array(
                                        'top'   => array(
                                            'style' => 'solid'
                                        ),
                                    )
                                ));*/
                            });
                        }
                    }
                    /*
                    $sheet->mergeCells('E1:F2');
                    $sheet->cells('E1:F2', function($cells) {
                        //背景颜色
                        $cells->setBackground( $this->rgb2html(153, 0, 153));
                        //居中
                        $cells->setAlignment('center');
                        //垂直居中
                        $cells->setValignment(\PHPExcel_Style_Alignment::VERTICAL_CENTER);
                    });
                    */
                });
            }
        })->export('xls');
    }

    function rgb2html($r, $g=-1, $b=-1)
    {
        if (is_array($r) && sizeof($r) == 3)
            list($r, $g, $b) = $r;

        $r = intval($r); $g = intval($g);
        $b = intval($b);

        $r = dechex($r<0?0:($r>255?255:$r));
        $g = dechex($g<0?0:($g>255?255:$g));
        $b = dechex($b<0?0:($b>255?255:$b));

        $color = (strlen($r) < 2?'0':'').$r;
        $color .= (strlen($g) < 2?'0':'').$g;
        $color .= (strlen($b) < 2?'0':'').$b;
        return '#'.$color;
    }

    public  function stringFromColumnIndex($pColumnIndex = 0) {
        $_indexCache = array();
        if (!isset($_indexCache[$pColumnIndex])) {
            // Determine column string
            if ($pColumnIndex < 26) {
                $_indexCache[$pColumnIndex] = chr(65 + $pColumnIndex);
            } elseif ($pColumnIndex < 702) {
                $_indexCache[$pColumnIndex] = chr(64 + ($pColumnIndex / 26)) .
                    chr(65 + $pColumnIndex % 26);
            } else {
                $_indexCache[$pColumnIndex] = chr(64 + (($pColumnIndex - 26) / 676)) .
                    chr(65 + ((($pColumnIndex - 26) % 676) / 26)) .
                    chr(65 + $pColumnIndex % 26);
            }
        }
        return $_indexCache[$pColumnIndex];
    }

    public function getsheets($id){
        $objects = Budget::where("project_id" ,"=" ,$id)->orderBy('budget_id', 'asc')->get();
        $configs = [];
        foreach($objects as $object) {
            $config = json_decode($object->sheet_data ,true);
            $config["id"] = $object->budget_id;
            $config["rows"] = [];

            $budget_rows_objects = BudgetRow::where("budget_id" ,"=" ,$object->budget_id)->orderBy('budget_row_id', 'asc')->get();
            if( count($budget_rows_objects) == 0 ){
                continue;
            }
            foreach ($budget_rows_objects as $budget_rows){
                $rows = json_decode($budget_rows->row_data ,true);
                array_unshift($rows ,"占位");
                $config["rows"][] = $rows;
            }
            $configs[] = $config;
        }
        return response()->json($configs);
    }


    public function cancel(Request $request ,$id){
        BudgetRow::where("budget_row_id" ,"=" ,$id)->update([
            "row_confirm_1"=>0,
            "row_confirm_2"=>0,
            "row_confirm_3"=>0
        ]);
        return response()->json(array("success"=>true));
    }


    protected function getEmptySheetData($rowsCount ,$colsCount){
        $rows = [];
        for($i = 0 ; $i < $rowsCount ;$i++) {
            $row = [];
            for ($j = 0; $j < $colsCount; $j++) {
                $row[] = "";
            }
            array_unshift($row ,"未保存");
            array_unshift($row ,0);
            $rows[] =$row;
        }
        return $rows;
    }

    protected function getEmptyColumns($rowsCount){
        $columns = [];
        for($i = 1 ; $i < $rowsCount ;$i++){
            $columns[] = array("data"=> $i);
        }
        return $columns;
    }

    protected function getRemove(&$org_sheets ,$cmp_id){
        $find = false;
        $index = -1;
        foreach ($org_sheets as $org_sheet){
            $index++;
            if($org_sheet->budget_id == $cmp_id){
                $find = array_splice($org_sheets ,$index ,1) ;
                break;
            }
        }
        return $find;
    }

    protected function getRemoveBudgetRow(&$org_rows ,$cmp_id){
        $find = false;
        $index = -1;
        foreach ($org_rows as $org_row){
            $index++;
            if($org_row->budget_row_id == $cmp_id){
                $find = array_splice($org_rows ,$index ,1) ;
                break;
            }
        }
        return $find;
    }

    protected function setChange($src_row ,$new_row ,$row_index ,$budget_id ,$settlement_id){
        if(false !== $src_row){
            $rows = json_decode( $src_row[0]->row_data ,true );
            if(!is_null($rows)){
                $src_len = count( $rows );
                $new_len = count( $new_row );
                for($i = 0 ; $i < $src_len ; $i++){
                    if( isset($new_row[$i])){
                        if( trim($rows[$i]) != trim($new_row[$i]) ){
                            $rowChanged = new BudgetRowChange();
                            $rowChanged->settlement_id = $settlement_id;
                            $rowChanged->budget_id = $budget_id;
                            $rowChanged->old_value = $rows[$i] ;
                            $rowChanged->new_value = $new_row[$i];
                            $rowChanged->row = $row_index + 1;
                            $rowChanged->col = $i + 1;
                            $rowChanged->save();
                        }
                    }else{

                    }
                }
            }
        }
    }

    public function saveBudgetRow( $settlement_id ,$budget_id ,$rows){
        $org_rows = DB::select('select * from `budget_row` where `budget_id` = ? order by `budget_row_id` asc', [$budget_id]);
        $i = 0;
        foreach ($rows as $row){
            $budget_row_id = array_shift( $row );
            array_shift($row);
            if( 0 == $budget_row_id ){
                $budget_row = new BudgetRow();
                $budget_row->budget_id = $budget_id;
                $budget_row->project_id = $settlement_id;
                $budget_row->row_data = json_encode($row);
                $budget_row->row_confirm_1 = 0;
                $budget_row->row_confirm_2 = 0;
                $budget_row->row_confirm_3 = 0;
                $budget_row->save();
            }else{
                $src_row = $this->getRemoveBudgetRow( $org_rows , $budget_row_id);
                $this->setChange( $src_row , $row ,$i ,$budget_id ,$settlement_id);
                BudgetRow::where("budget_row_id" ,"=" ,$budget_row_id)->update(["row_data"=>json_encode($row)]);
                $i++;
            }
        }

        foreach ($org_rows as $org_row){
            $tmp["delete_id"][] = $org_row->budget_row_id;
            BudgetRow::where("budget_row_id" ,"=" ,$org_row->budget_row_id)->delete();
        }

    }

    public function sheet(Request $request , $settlement_id ,$budget_id){
        return response()->json( array("success"=>true ,"sheets"=>$this->getSheet( $settlement_id ,$budget_id ,false)) );
    }

    public function getSheet($settlement_id ,$budget_id ,$encode_json = true){
        $Budget = Budget::where("project_id" ,"=" ,$settlement_id)->where("budget_id" ,"=" ,$budget_id)->first();
        $budget_rows_objects = BudgetRow::where("budget_id" ,"=" ,$budget_id)->orderBy('budget_row_id', 'asc')->get();
        $config = json_decode($Budget->sheet_data ,true);
        $config["id"] = $Budget->budget_id;
        $config["rows"] = [];
        $rows_count = 0;
        foreach ($budget_rows_objects as $budget_rows){
            $rows = json_decode($budget_rows->row_data ,true);
            $str = array();
            if($budget_rows->row_confirm_1 == 1){
                $str[] = "业主已确认";
            }else{
                $str[] = "业主未确认";
            }
            if($budget_rows->row_confirm_2 == 1){
                $str[] = "承包单位已确认";
            }else{
                $str[] = "承包单位未确认";
            }
            if($budget_rows->row_confirm_3 == 1){
                $str[] = "中咨询单位已确认";
            }else{
                $str[] = "咨询单位未确认";
            }
            array_unshift($rows ,"取消|" .join("-",$str));
            array_unshift($rows ,$budget_rows->budget_row_id);

            $count = count($rows);
            if($rows_count < $count){
                $rows_count = $count;
            }
            $config["rows"][] = $rows;
        }
        $config["columns"] = [];//隐藏第一列
        for($i = 1 ; $i < $rows_count ;$i++){
            $config["columns"][] = array("data"=> $i);
        }

        if($encode_json){
            return json_encode($config);
        }else{
            return $config;
        }
    }

    public function getBudget2($id){
        $Budgets = [];
        $objects = Budget::where("project_id" ,"=" ,$id)->orderBy('budget_id', 'asc')->get();
        foreach($objects as $object) {
            $budget_rows_objects = BudgetRow::where("budget_id", "=", $object->budget_id)->orderBy('budget_row_id', 'asc')->get();
            if (count($budget_rows_objects) == 0) {
                continue;
            }
            $Budgets[] = "{$id}/{$object->budget_id}";
        }
        return $Budgets;
    }

    public function getBudget($id ,$encode_json = true){
        $Budgets = [];
        $objects = Budget::where("project_id" ,"=" ,$id)->orderBy('budget_id', 'asc')->get();

        foreach($objects as $object) {
            $budget_rows_objects = BudgetRow::where("budget_id" ,"=" ,$object->budget_id)->orderBy('budget_row_id', 'asc')->get();
            if(count($budget_rows_objects) == 0){
                continue;
            }
            $config = json_decode($object->sheet_data ,true);
            $config["id"] = $object->budget_id;
            $config["rows"] = [];
            $rows_count = 0;
            foreach ($budget_rows_objects as $budget_rows){
                $rows = json_decode($budget_rows->row_data ,true);
                $str = array();
                if($budget_rows->row_confirm_1 == 1){
                    $str[] = "业主已确认";
                }else{
                    $str[] = "业主未确认";
                }
                if($budget_rows->row_confirm_2 == 1){
                    $str[] = "承包单位已确认";
                }else{
                    $str[] = "承包单位未确认";
                }
                if($budget_rows->row_confirm_3 == 1){
                    $str[] = "咨询单位已确认";
                }else{
                    $str[] = "咨询单位未确认";
                }
                array_unshift($rows ,"取消|" .join("-",$str));
                array_unshift($rows ,$budget_rows->budget_row_id);

                $count = count($rows);
                if($rows_count < $count){
                    $rows_count = $count;
                }
                $config["rows"][] = $rows;
            }
            $config["columns"] = [];//隐藏第一列
            for($i = 1 ; $i < $rows_count ;$i++){
                $config["columns"][] = array("data"=> $i);
            }
            if($encode_json){
                $Budgets[] = str_replace('"', '\\"', str_replace("'" ,"\\'",json_encode($config)));
            }else{
                $Budgets[] = $config;
            }
        }
        return $Budgets;
    }

    public function save( Request $request ){
        $settlement_id = $request->get("project_id");
        if($request->ajax()){
            $sheet = json_decode( $request->getContent() ,true);
            if(is_null($sheet)){
                return response()->json(array("success"=>false));
            }
            //foreach($sheets as $sheet){
                $budget_id = $sheet["id"];
                $rows = $sheet["rows"];
                unset($sheet["rows"]);
                if(0 == $budget_id){
                    $budget = new Budget();
                    $budget->project_id = $settlement_id;
                    $budget->sheet_name = $sheet["sheet_name"];
                    $budget->sheet_data = json_encode($sheet);
                    $budget->save();
                    $budget_id = $budget->id;
                }else{
                    Budget::where("budget_id" ,"=" ,$budget_id)->update(["sheet_data"=>json_encode($sheet) ,"sheet_name"=>$sheet["sheet_name"]]);
                }
                $this->saveBudgetRow( $settlement_id ,$budget_id ,$rows);
            //}
        }else{
            return response()->json(array("success"=>false));
        }
        return response()->json( array("success"=>true ,"sheets"=>$this->getSheet( $settlement_id ,$budget_id ,false)) );
        //return response()->json( array("success"=>true ,"sheets"=>$this->getBudget( $settlement_id ,false )) );
    }

    public function delete( Request $request ){
        $id = Input::get("id");
        if($request->ajax()){
            Budget::where("budget_id" ,"=" ,$id)->delete();
            BudgetRow::where("budget_id" ,"=" ,$id)->delete();
            return response()->json(array("success"=>true));
        }
        return response()->json(array("success"=>false));
    }

}